#include "Common.h" 
#include <Diagnostics.h> 
#include <ServiceRuntime.h> 

static void WriteToLog(DiagnosticLogLevel level, LPCWSTR msg) 
{ 
    HRESULT hr = DiagnosticsWriteToLog(level,msg); 
    if(FAILED(hr))  
    { 
        throw "Error writing to log.";
    } 
} 
void InitializeRoleEnvironment() 
{ 
	// Already initialized?
	static bool initialized = false;
	if (initialized)
		return;

	// Initialize role environment
    HRESULT hr = RoleEnvironmentInitialize(); 
    if(FAILED(hr)) 
    { 
        throw "Error in initalize"; 
    }
	initialized = true;
} 
void InitializeLogging() 
{ 
	// Initialize role environment
    InitializeRoleEnvironment();

	// Already initialized?
	static bool initialized = false;
	if (initialized)
		return;

	// Initialize logging
    WCHAR diagnosticStorePath[MAX_PATH];
    LPLOCALRESOURCE diagnosticStoreLocalResource = NULL;
	HRESULT loggingHr = NULL;

	loggingHr = RoleEnvironmentGetLocalResourceW(L"DiagnosticStore", &diagnosticStoreLocalResource);
    if(FAILED(loggingHr)) 
    { 
        throw "Error in initalize"; 
    } 

    loggingHr = LocalResourceGetRootPathW(diagnosticStoreLocalResource, diagnosticStorePath, MAX_PATH, NULL);
    if(FAILED(loggingHr)) 
    { 
        throw "Error in initalize"; 
    } 

    loggingHr = DiagnosticsInitialize(diagnosticStorePath);
    if(FAILED(loggingHr)) 
    { 
        throw "Error in initalize"; 
    } 
	initialized = true;
} 
void LogCritical(LPCWSTR message) 
{ 
	WriteToLog(DiagnosticLogLevel::LlCritical,message); 
} 
void LogError(LPCWSTR message) 
{ 
    WriteToLog(DiagnosticLogLevel::LlError,message); 
} 
void LogWarning(LPCWSTR message) 
{ 
    WriteToLog(DiagnosticLogLevel::LlWarning,message); 
} 
void LogInformation(LPCWSTR message) 
{ 
    WriteToLog(DiagnosticLogLevel::LlInformation,message); 
} 
void LogVerbose(LPCWSTR message) 
{ 
    WriteToLog(DiagnosticLogLevel::LlVerbose,message); 
} 

std::string GetConfigurationSetting(LPCSTR key)
{
    CHAR sbuf[512];  
    LPSTR buf = sbuf;
    size_t len = sizeof(sbuf);
    size_t required;
    HRESULT hr = RoleEnvironmentGetConfigurationSettingValueA(key,buf,len,&required);
    if(hr == ROLE_ENVIRONMENT_E_INSUFFICIENT_BUFFER)
    {
        buf = new CHAR[required];
        hr = RoleEnvironmentGetConfigurationSettingValue(key,buf,required,NULL);
    }
    if(FAILED(hr))
    {
        if(buf != sbuf)
        {
            delete buf;
        }
        throw  "Error reading configuration setting."; 
    }
    else 
    {
        std::string ret(buf);
        if(buf != sbuf)
        {
            delete buf;
        }
        return ret;
    }
}

std::string GetLocalResourceRootPath(LPCSTR name)
{
	LPLOCALRESOURCE resource = NULL;
	RoleEnvironmentGetLocalResource(name, &resource);

    CHAR sbuf[512];  
    LPSTR buf = sbuf;
    size_t len = sizeof(sbuf);
    size_t required;
    HRESULT hr = LocalResourceGetRootPath(resource,buf,len,&required);
    if(hr == ROLE_ENVIRONMENT_E_INSUFFICIENT_BUFFER)
    {
        buf = new CHAR[required];
        hr = LocalResourceGetRootPath(resource,buf,len,NULL);
    }
    if(FAILED(hr))
    {
        if(buf != sbuf)
        {
            delete buf;
        }
        throw  "Error reading local resource path setting."; 
    }
    else 
    {
        std::string ret(buf);
        if(buf != sbuf)
        {
            delete buf;
        }
        return ret;
    }
}

long GetLocalResourceRootPathSize(LPCSTR name)
{
	LPLOCALRESOURCE resource = NULL;
	RoleEnvironmentGetLocalResource(name, &resource);

	ULONG size = 0;
    HRESULT hr = LocalResourceGetMaximumSizeInMegabytes(resource, &size);
    if(FAILED(hr))
    {
        throw  "Error reading local resource path setting."; 
    }
    else 
    {
        return (long)size;
    }
}